package com.ruoyi;

import cn.hutool.core.util.ReUtil;
import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.Expression;
import org.activiti.bpmn.model.*;
import org.activiti.bpmn.model.Process;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricActivityInstanceQuery;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.impl.persistence.entity.ExecutionEntityImpl;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.activiti.image.ProcessDiagramGenerator;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.apache.commons.lang3.StringUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.*;
import java.util.*;

public class ActivitiInstanceTest {
    public static String definitionKey="lossevent_7";
    ProcessEngine processEngine = null;
    RuntimeService runtimeService=null;

    @Before
    public void before() {
        //提前加载这个
        Expression compiledExp = AviatorEvaluator.compile("a>1");
        //创建ProcessEngineConfiguration对象
        ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
        processEngine = configuration.buildProcessEngine();
        //获取RuntimeService对象
        runtimeService = processEngine.getRuntimeService();


    }

    @After
    public void after() {
        if (processEngine != null) {
            processEngine.close();
        }
    }

    @Test
    public void testStart() {
        // 1
        String businessKey = "12222211";
        //2
        Map<String, Object> variables=new HashMap<>();
        variables.put("user","admin");
        variables.put("acti_num",4);
        variables.put("acti_go",false);
        variables.put("acti_back",true);
        // 3
        String startDefinitionKey=definitionKey;
        //ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(startDefinitionKey, businessKey,variables);

        ProcessInstance processInstance = runtimeService.startProcessInstanceById("lossevent_6:16:e39b3014-4fe7-11eb-96d2-b0359fadfbca", businessKey,variables);

        System.out.println(ActivitiFormateUtils.formateProcessInstance(processInstance,null));
    }



    @Test
    //查询
    public void testQuery() {
        String processInstanceId="";
        List<ProcessInstance> list  = processEngine.getRuntimeService()
                .createProcessInstanceQuery()
                .processInstanceId("20001")
               // .processInstanceBusinessKey("1")
                //.processDefinitionKey("lossevent_6")
                .list();
               // .singleResult();//返回的数据要么是单行，要么是空 ，其他情况报错
        System.out.println(list.size());


        for (ProcessInstance processInstance : list) {
            System.out.println(processInstance.getProcessInstanceId());
        }
        //判断流程实例的状态
        if(list.size()>0){
            ProcessInstance pi=list.get(0);
           // System.out.println("该流程实例"+processInstanceId+"正在运行...  "+"当前活动的任务:"+pi.getActivityId());

            System.out.println(ActivitiFormateUtils.formateProcessInstance(pi,null));

            ActivitiUtils.resolvTask(processEngine,pi);
        }else{
            System.out.println("当前的流程实例"+processInstanceId+" 已经结束！");


        }

    }


    @Test
    //单个流程实例挂起和激活
    public void testActivateOrSuspend() {
        String processInstanceId = "12501";
        RuntimeService runtimeService = processEngine.getRuntimeService();
        List<ProcessInstance> processInstanceList = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).list();
        for (ProcessInstance processInstance : processInstanceList) {
            boolean suspended = processInstance.isSuspended();
            if (suspended) {
                runtimeService.activateProcessInstanceById(processInstance.getProcessInstanceId());
                System.out.println("流程实例" + processInstance.getProcessDefinitionId() + "激活");
            } else {
                runtimeService.suspendProcessInstanceById(processInstance.getProcessInstanceId());
                System.out.println("流程实例" + processInstance.getProcessDefinitionId() + "挂起");
            }
        }

    }








    public void instanceALL2( String processInstanceId ,String processDefinitionId)  {
        //获取HistoryService对象
        HistoryService historyService = processEngine.getHistoryService();
        // 获取历史流程实例
        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().
                processInstanceId(processInstanceId).singleResult();
        // 获取流程中已经执行的节点，按照执行先后顺序排序
        List<HistoricActivityInstance> historicActivityInstanceList = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(processInstanceId).
                orderByHistoricActivityInstanceId().asc().list();

        // 构造已执行的节点ID集合
        List<String> executedActivityIdList = new ArrayList<String>();
        for (HistoricActivityInstance activityInstance : historicActivityInstanceList) {
            executedActivityIdList.add(activityInstance.getActivityId());
        }

        //获取RepositoryService对象
        RepositoryService repositoryService = processEngine.getRepositoryService();
        // 获取bpmnModel
        BpmnModel bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId());

        // 获取流程已发生流转的线ID集合
        List<String> flowIds = this.getExecutedFlows(bpmnModel, historicActivityInstanceList);



    }

    private List<String> getExecutedFlows(BpmnModel bpmnModel,
                                          List<HistoricActivityInstance> historicActivityInstanceList) {
        List<String> executedFlowIdList = new ArrayList<>();
        for (int i = 0; i < historicActivityInstanceList.size() - 1; i++) {
            HistoricActivityInstance hai = historicActivityInstanceList.get(i);
            FlowNode flowNode = (FlowNode) bpmnModel.getFlowElement(hai.getActivityId());
            List<SequenceFlow> sequenceFlows = flowNode.getOutgoingFlows();
            if (sequenceFlows.size() > 1) {
                HistoricActivityInstance nextHai = historicActivityInstanceList.get(i + 1);
                sequenceFlows.forEach(sequenceFlow -> {
                    if (sequenceFlow.getTargetFlowElement().getId().equals(nextHai.getActivityId())) {
                        executedFlowIdList.add(sequenceFlow.getId());
                    }
                });
            } else if (sequenceFlows.size() == 1) {
                executedFlowIdList.add(sequenceFlows.get(0).getId());
            }
        }
        return executedFlowIdList;
    }



}
